package com.test.profiler


import java.util._
import java.io.StringWriter
import java.io.IOException
import collection.{JavaConversions, mutable}


/**
 *
 * User: adenysenko
 * Date: Jan 12, 2007
 * Time: 1:18:28 PM
 *
 */
object CPUProfiler {
  private var frameStats = new FrameStats

  def clearStats(){
    frameStats = new FrameStats
  }

  def include(thread: Array[StackTraceElement]):Boolean = {
    if (thread.length > 0) {
      var loc: String = getMeth(thread(0))
      if (loc.equals("java.lang.Object.wait") || loc.equals("java.lang.Thread.sleep")) {
        false
      }
    }
    true
  }

  def gatherStatsNow(){
    var all: Map[Thread, Array[StackTraceElement]] = Thread.getAllStackTraces
    var currentThread: Thread = Thread.currentThread
    for (t <- JavaConversions.asSet(all.keySet)) {
      if (t != currentThread) {
        var thread: Array[StackTraceElement] = all.get(t)
        if (include(thread)) {
          var nestedStats: FrameStats = frameStats
          var i: Int = thread.length - 1
          while (i >= 0) {
              var loc: String = getMeth(thread(i))
              nestedStats = nestedStats.recordNestedInvocation(loc)
              if (loc.startsWith("org.apache.coyote.tomcat5.CoyoteWriter") || loc.startsWith("org.apache.coyote.tomcat5.CoyoteOutputStream")) {
                i = -1
              }
              i -= 1
          }
        }
      }
    }
  }

  def hotSpots: mutable.HashMap[String,Long] = {
    val m = new mutable.HashMap[String,Long]
    frameStats.collectHotSpots(m)
    return m
  }

  def getResult(filter: FrameStats.Filter): String = {
    var w: StringWriter = new StringWriter
    try {
      frameStats.print(w, filter)
    }
    catch {
      case e: IOException => {
        e.printStackTrace
      }
    }
    return w.toString
  }

  def hotSpotsNoNest: mutable.HashMap[String,Long] = {
    val m = new mutable.HashMap[String,Long]
    frameStats.collectHotSpotsNoNest(m)
    return m
  }
  def getMeth(e: StackTraceElement): String = {
    return e.getClassName + "." + e.getMethodName
  }
}


